package org.solr;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.ZkCoreNodeProps;
import org.apache.solr.common.params.MapSolrParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.zookeeper.KeeperException;

/**
 * @author Administrator
 * 
 */
public class CreateIndex {
	public static long startTime = 0;
	public static long indexCount = 0;
	static long endTime;
	static long tagTime;
	final static Random rnd = new Random();
	static String zkHost = "localhost:2181";
	static String defaultCollection = "collection1";
	static int zkClientTimeout = 60000;
	static int zkConnectTimeout = 5000;
	private String Base_URL;
	static SolrServer solrServer;
	
	
	public void solrStatus() throws InterruptedException,
			TimeoutException, IOException, KeeperException {

		CloudSolrServer Server = new CloudSolrServer(zkHost);
		Server.connect();

		Set<String> collections = Server.getZkStateReader().getClusterState()
				.getCollections();

		Set<String> liveNodes = Server.getZkStateReader().getClusterState()
				.getLiveNodes();

		// 列出collection
		for (String collection : collections) {
			System.out.format("collection:%s\n", collection);
			Map<String, Slice> Slices = Server.getZkStateReader()
					.getClusterState().getSlices(collection);

			// 列出leader的状态
			for (String slice : Slices.keySet()) {
				ZkCoreNodeProps leaderProps = new ZkCoreNodeProps(Server
						.getZkStateReader().getLeaderProps(collection, slice));
				for (String liveNode : liveNodes) {
					System.out.format("\t\tBaseUrl:%s...%s\n", leaderProps
							.getBaseUrl(), leaderProps.getCoreNodeName()
							.contains(liveNode));
				}
			}

			// 列出replica的状态
			for (Slice slice : Slices.values()) {
				System.out.format("\tslice:%s\n", slice.getName());
				Collection<Replica> rep = slice.getReplicas();
				for (Replica replica : rep) {
					for (String liveNode : liveNodes) {
						System.out.format("\t\tLive Replica:%s...%s\n",
								replica.getName(),
								replica.getName().contains(liveNode));
					}
				}
			}

		}

	}

	public static ArrayList<String> getLiveBaseUrl(String zkHost) {
		ArrayList<String> LiveBaseUrl = new ArrayList<String>();

		try {
			CloudSolrServer Server = new CloudSolrServer(zkHost);

			Server.connect();

			Set<String> liveNodes = Server.getZkStateReader().getClusterState()
					.getLiveNodes();

			Set<String> collections = Server.getZkStateReader()
					.getClusterState().getCollections();
			for (String collection : collections) {
				Map<String, Slice> slices = Server.getZkStateReader()
						.getClusterState().getSlices(collection);

				for (String slice : slices.keySet()) {
					ZkCoreNodeProps leaderProps;
					try {
						leaderProps = new ZkCoreNodeProps(Server
								.getZkStateReader().getLeaderProps(collection,
										slice));
						for (String liveNode : liveNodes) {
							if (leaderProps.getCoreNodeName()
									.contains(liveNode))
								LiveBaseUrl.add(leaderProps.getBaseUrl());
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
						continue;
					}

				}
			}
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		}

		return LiveBaseUrl;

	}

	public static void ServerAdd(String solrServerUrl,
			Collection<SolrInputDocument> docs) {
		ConcurrentUpdateSolrServer server = new ConcurrentUpdateSolrServer(
				solrServerUrl, 10000, 5);
		try {
			server.add(docs);
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void ConRun() throws SolrServerException, IOException {
		
		ConcurrentUpdateSolrServer server;
		server = new ConcurrentUpdateSolrServer(
				"http://localhost:8983/solr/collection1", 10000, 5);
		
		
//		ArrayList<String> solrServerUrl = getLiveBaseUrl(zkHost);
//		if (solrServerUrl.size() > 0) {
//			server = new ConcurrentUpdateSolrServer(
//					"http://localhost:8983/solr/collection1", 10000, 5);
//			System.out.println("http://localhost:8983/solr/collection1");
//		} else {
//			System.out.println("no live server...");
//			return;
//		}
//		server.deleteById("*:*");
//		server.commit();
		Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
		
		int i = 0;
		for (i = 0; i < 2000; i++) {
			tagTime = System.currentTimeMillis();
			for (int j = 0; j < 10000; j++) {
				SolrInputDocument doc = new SolrInputDocument();
				doc.setField("id", j + "[" + System.currentTimeMillis() + "]"
						+ rnd.nextInt(99999999));
				doc.setField("name", "name" + (System.currentTimeMillis()));
				docs.add(doc);
			}
			server.add(docs);
			System.out.println("add data ok... "
					+ (System.currentTimeMillis() - tagTime));
			docs.clear();
		}
		
		tagTime = System.currentTimeMillis();
		System.out.println("add docs ok... "	+ (System.currentTimeMillis() - tagTime));
//		server.commit();
//		System.out.println("commit ok... "	+ (System.currentTimeMillis() - tagTime));
//		server.shutdown();

		// tagTime = System.currentTimeMillis();
		// server.optimize();
		// System.out.println("optimize ok... "
		// + (System.currentTimeMillis() - tagTime));

	}

	public static void SingleRun() throws SolrServerException, IOException,
			InterruptedException {


		
		CloudSolrServer solrServer = new CloudSolrServer(zkHost);
		solrServer.setDefaultCollection(defaultCollection);
		solrServer.setZkClientTimeout(zkClientTimeout);
		solrServer.setZkConnectTimeout(zkConnectTimeout);
		
		Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
		tagTime = System.currentTimeMillis();
		long count = 0;
		int j = 0;
		for (int i = 0; i < 20; i++) {
			for (j = 0; j < 1000; j++) {
				SolrInputDocument doc = new SolrInputDocument();
//				doc.setField("id", count);
				doc.setField("type", count % 7);
				doc.setField("text", "english name 中华人民共和国,english name 中华人民共和国");// + System.currentTimeMillis());
				doc.setField("exfile", count % 7);
				docs.add(doc);
				count++;
			}

			try {
				solrServer.add(docs);
			} catch (SolrServerException e) {
				Thread.sleep(1000);
				solrServer.shutdown();
				solrServer = new CloudSolrServer(zkHost);
				i--;
				continue;
			} catch (IOException e) {
				Thread.sleep(1000);
				solrServer.shutdown();
				solrServer = new CloudSolrServer(zkHost);
				i--;
				continue;
			}
			j = j * (i + 1);
			docs.clear();
		}
		System.out.format("add data [%s] ok... %s ms,%sper/sec\n", j,
				(System.currentTimeMillis() - tagTime),
				(j * 1000 / (System.currentTimeMillis() - tagTime)));

		tagTime = System.currentTimeMillis();
		solrServer.commit();
		System.out.println("commit ok... "
				+ (System.currentTimeMillis() - tagTime));				

	}

	public void MultiRun(final int threadCounts)
			throws SolrServerException, IOException {

		ExecutorService pool = Executors.newFixedThreadPool(threadCounts);

		final int zkClientTimeout = 15000;
		final int zkConnectTimeout = 5000;

		CloudSolrServer[] cloudSolrServer = new CloudSolrServer[threadCounts];
		for (int i = 0; i < threadCounts; i++) {
			cloudSolrServer[i] = new CloudSolrServer(zkHost);
			cloudSolrServer[i].setDefaultCollection("collection" + (i % 5));
			cloudSolrServer[i].setZkClientTimeout(zkClientTimeout);
			cloudSolrServer[i].setZkConnectTimeout(zkConnectTimeout);
		}

		// cloudSolrServer[0] = new CloudSolrServer(zkHost);
		// cloudSolrServer[0].setDefaultCollection("collection1");
		// cloudSolrServer[0].setZkClientTimeout(zkClientTimeout);
		// cloudSolrServer[0].setZkConnectTimeout(zkConnectTimeout);
		//
		// cloudSolrServer[1] = new CloudSolrServer(zkHost);
		// cloudSolrServer[1].setDefaultCollection("collection2");
		// cloudSolrServer[1].setZkClientTimeout(zkClientTimeout);
		// cloudSolrServer[1].setZkConnectTimeout(zkConnectTimeout);

		// byte[] text = new byte[100];
		final String btext = "2500年前，人们飞鸽传书;170年前，莫尔斯发明了电报;37年前，第一封电子邮件发出;今天，QQ邮箱联系你、我、他。";
		tagTime = System.currentTimeMillis();
		for (int i = 0; i < 2000; i++) {
			Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
			for (int j = 0; j < 100000; j++) {

				SolrInputDocument doc = new SolrInputDocument();
				doc.addField("id", j + '_' + System.currentTimeMillis() + '_'
						+ rnd.nextInt(99999999));
				doc.addField("type", i);
				doc.addField("name", "name" + System.currentTimeMillis());
				doc.addField("contect", "contect_" + btext);
				docs.add(doc);
			}
			pool.execute(new IndexThread(cloudSolrServer[(i % threadCounts)],
					docs));

			if (i % 10 == 0 && i > 10) {
				try {
					System.out.println("do sleep...");
					Thread.sleep(60000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

		System.out.println("start threads ok... "
				+ (System.currentTimeMillis() - tagTime));
	}

	
	 public static void search(CloudSolrServer solrServer, String String) {        
	        SolrQuery solrQuery = new SolrQuery();
	        HashMap<String,String> map = new HashMap<String,String>();
	        map.put("wt","json");
	        SolrParams params = new MapSolrParams(map);
	        solrQuery.add(params);
	        solrQuery.setFields("id");
	        solrQuery.setQuery(String);	        
	        solrQuery.setRows(10000);
	  
	        try {  
	            QueryResponse response = solrServer.query(solrQuery);  
	            SolrDocumentList docs = response.getResults();	            	            
	  
	            System.out.println("文档个数：" + docs.getNumFound());  
	            System.out.println("查询时间：" + response.getQTime());  
	  
//	            for (SolrDocument doc : docs) {  
//	                String name = (String) doc.getFieldValue("name");  
//	                String id = (String) doc.getFieldValue("id");  
//	                System.out.println("id: " + id);  
//	                System.out.println("name: " + name);  
//	                System.out.println();  
//	            }  
	        } catch (SolrServerException e) {  
	            e.printStackTrace();  
	        } catch(Exception e) {  
	            System.out.println("Unknowned Exception!!!!");  
	            e.printStackTrace();  
	        }  
	    }  
	 
	public void doQuery() throws MalformedURLException{
		CloudSolrServer cloudServer = new CloudSolrServer(zkHost);
		
		cloudServer.setDefaultCollection(defaultCollection);
		cloudServer.setZkClientTimeout(zkClientTimeout);
		cloudServer.setZkConnectTimeout(zkConnectTimeout);
		search(cloudServer,"*:*");
	
	}
	
	
	
	
	public static void main(String[] argv) throws SolrServerException,
			IOException, InterruptedException, TimeoutException,
			KeeperException {
		
		SingleRun();
//		MultiRun(5);
//		 ConRun();
//		 solrStatus();
//		doQuery();
	}
}

class IndexThread implements Runnable {
	private Collection<SolrInputDocument> docs;
	private CloudSolrServer cloudSolrServer;

	public IndexThread(CloudSolrServer cloudSolrServer,
			Collection<SolrInputDocument> docs) {
		this.docs = docs;
		this.cloudSolrServer = cloudSolrServer;
	}

	@Override
	public void run() {
		long tagTime;
		try {
			tagTime = System.currentTimeMillis();
			if (CreateIndex.startTime == 0) {
				CreateIndex.startTime = tagTime;
			}
			cloudSolrServer.add(docs);
			CreateIndex.indexCount += 100000;
			System.out.println(Thread.currentThread().getName()
					+ "index ok... " + (System.currentTimeMillis() - tagTime));

			System.out
					.format("run=%s,count=%s,avg=%s\n",
							System.currentTimeMillis() - CreateIndex.startTime,
							CreateIndex.indexCount,
							CreateIndex.indexCount
									* 1000
									/ (System.currentTimeMillis() - CreateIndex.startTime));

			// tagTime = System.currentTimeMillis();
			// cloudSolrServer.commit();
			// System.out.println(Thread.currentThread().getName() +
			// "commit ok... "
			// + (System.currentTimeMillis() - tagTime));
			//
			// tagTime = System.currentTimeMillis();
			// cloudSolrServer.optimize();
			// System.out.println(Thread.currentThread().getName() +
			// "optimize ok... "
			// + (System.currentTimeMillis() - tagTime));
		} catch (SolrServerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
